//
//  HHMessagesViewController+UIMenu.m
//  HHChatKit
//
//  Created by Henry on 2021/8/23.
//

#import "HHMessagesViewController+UIMenu.h"
#import <objc/runtime.h>

#define UIMenuSELPrefix     @"HHMessage_Menu_"

@interface HHMessagesViewController ()

@property (nonatomic, strong) NSMutableArray *menuItems;
@property (nonatomic, copy) void(^clickMenuCompletion)(NSString *menuTitle, HHMessagesViewController *label);

@end

@interface SelectMenuForwardingTarget : NSObject

@end

@implementation SelectMenuForwardingTarget

- (void)forwardingSelector:(NSString *)selectorName controller:(HHMessagesViewController *)controller {
    NSString *menuTitle = [selectorName stringByReplacingOccurrencesOfString:UIMenuSELPrefix withString:@""];
    if (controller.clickMenuCompletion) {
        controller.clickMenuCompletion(menuTitle, controller);
    }
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSString *selectorName = NSStringFromSelector(sel);
    if ([selectorName hasPrefix:UIMenuSELPrefix]) {
        class_addMethod([self class], sel, imp_implementationWithBlock(^(id self, NSString *str) {
//            NSLog(@"imp block, sel = %@", selectorName);
        }), "v@");
    }
    return [super resolveInstanceMethod:sel];
}

@end


@implementation HHMessagesViewController (UIMenu)

static char menuItemsKey;

- (void)setMenuItems:(NSMutableArray *)menuItems {
    objc_setAssociatedObject(self, &menuItemsKey, menuItems, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSMutableArray *)menuItems {
    return objc_getAssociatedObject(self, &menuItemsKey);
}

static char clickMenuCompletionKey;

- (void)setClickMenuCompletion:(void (^)(NSString *, HHMessagesViewController *))clickMenuCompletion {
    objc_setAssociatedObject(self, &clickMenuCompletionKey, clickMenuCompletion, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void (^)(NSString *, HHMessagesViewController *))clickMenuCompletion {
    return objc_getAssociatedObject(self, &clickMenuCompletionKey);
}

- (void)showSelectWithMenus:(NSArray<NSString *> *)menus inView:(UIView *)inView clickMenuCompletion:(void (^)(NSString * _Nonnull, HHMessagesViewController * _Nonnull))clickMenuCompletion {
    if (menus.count == 0) {
        return;
    }
    self.clickMenuCompletion = clickMenuCompletion;
    
    NSMutableArray *menuItems = [NSMutableArray array];
    for (NSString *str in menus) {
        NSString *selectorName = [NSString stringWithFormat:@"%@%@", UIMenuSELPrefix, str];
        UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:str action: NSSelectorFromString(selectorName)];
        [menuItems addObject:menuItem];
    }
    self.menuItems = menuItems;
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerDidHide) name:UIMenuControllerDidHideMenuNotification object:nil];
    [self becomeFirstResponder];

    UIMenuController *controller = [UIMenuController sharedMenuController];
    controller.menuItems = menuItems;
    [controller setTargetRect:inView.bounds inView:inView];
    [controller setMenuVisible:YES animated:YES];

}


#pragma mark - UIResponder

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    NSString *selectorName = NSStringFromSelector(action);
    if ([selectorName hasPrefix:UIMenuSELPrefix]) {
        return YES;
    }
    return [super canPerformAction:action withSender:sender];
}

- (id)forwardingTargetForSelector:(SEL)aSelector {
    NSString *selectorName = NSStringFromSelector(aSelector);
    if ([selectorName hasPrefix:UIMenuSELPrefix]) {
        SelectMenuForwardingTarget *target = [SelectMenuForwardingTarget new];
        __weak typeof(self)wSelf = self;
        [target forwardingSelector:selectorName controller:wSelf];
        return target;
    } else {
        return [super forwardingTargetForSelector:aSelector];
    }
}

- (void)menuControllerDidHide {
    [self hideMenuItems];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil];
}

- (void)hideMenuItems {
    if (self.menuItems.count > 0) {
        NSMutableArray *newMenuItems = [NSMutableArray array];
        NSArray *customMenuTitle = [self.menuItems valueForKeyPath:@"title"];
        for (UIMenuItem *menuItem in [UIMenuController sharedMenuController].menuItems) {
            if (![customMenuTitle containsObject:menuItem.title]) {
                [newMenuItems addObject:menuItem];
            }
        }
        [UIMenuController sharedMenuController].menuItems = newMenuItems;
    }
    UIView *allTextSelectBackView = [self.view viewWithTag:[@"allTextSelectBackView" hash]];
    [allTextSelectBackView removeFromSuperview];
    allTextSelectBackView = nil;
}

@end
